home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / bosco.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  10KB  |  436 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12.  
  13. #define MAX_STARS 250
  14. #define STARS_COLOR_BASE 32
  15.  
  16. unsigned char *bosco_staronoff;
  17. unsigned char *bosco_starblink;
  18. static unsigned int stars_scrollx;
  19. static unsigned int stars_scrolly;
  20. static unsigned char bosco_scrollx,bosco_scrolly;
  21. static unsigned char bosco_starcontrol;
  22. static int flipscreen;
  23. static int displacement;
  24.  
  25.  
  26. struct star
  27. {
  28.     int x,y,col,set;
  29. };
  30. static struct star stars[MAX_STARS];
  31. static int total_stars;
  32.  
  33. #define VIDEO_RAM_SIZE 0x400
  34.  
  35. unsigned char *bosco_videoram2,*bosco_colorram2;
  36. unsigned char *bosco_radarx,*bosco_radary,*bosco_radarattr;
  37. size_t bosco_radarram_size;
  38.                                             /* to speed up video refresh */
  39. static unsigned char *dirtybuffer2;    /* keep track of modified portions of the screen */
  40.                                             /* to speed up video refresh */
  41. static struct osd_bitmap *tmpbitmap1;
  42.  
  43.  
  44.  
  45. static struct rectangle spritevisiblearea =
  46. {
  47.     0*8+3, 28*8-1,
  48.     0*8, 28*8-1
  49. };
  50.  
  51. static struct rectangle spritevisibleareaflip =
  52. {
  53.     8*8, 36*8-1-3,
  54.     0*8, 28*8-1
  55. };
  56.  
  57.  
  58. static struct rectangle radarvisiblearea =
  59. {
  60.     28*8, 36*8-1,
  61.     0*8, 28*8-1
  62. };
  63.  
  64. static struct rectangle radarvisibleareaflip =
  65. {
  66.     0*8, 8*8-1,
  67.     0*8, 28*8-1
  68. };
  69.  
  70.  
  71.  
  72. void bosco_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  73. {
  74.     int i;
  75.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  76.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  77.  
  78.  
  79.     for (i = 0;i < 32;i++)
  80.     {
  81.         int bit0,bit1,bit2;
  82.  
  83.  
  84.         bit0 = (color_prom[31-i] >> 0) & 0x01;
  85.         bit1 = (color_prom[31-i] >> 1) & 0x01;
  86.         bit2 = (color_prom[31-i] >> 2) & 0x01;
  87.         palette[3*i] = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  88.         bit0 = (color_prom[31-i] >> 3) & 0x01;
  89.         bit1 = (color_prom[31-i] >> 4) & 0x01;
  90.         bit2 = (color_prom[31-i] >> 5) & 0x01;
  91.         palette[3*i + 1] = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  92.         bit0 = 0;
  93.         bit1 = (color_prom[31-i] >> 6) & 0x01;
  94.         bit2 = (color_prom[31-i] >> 7) & 0x01;
  95.         palette[3*i + 2] = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  96.     }
  97.  
  98.     /* characters / sprites */
  99.     for (i = 0;i < 64*4;i++)
  100.     {
  101.         colortable[i] = 15 - (color_prom[i + 32] & 0x0f);    /* chars */
  102.         colortable[i+64*4] = 15 - (color_prom[i + 32] & 0x0f) + 0x10;    /* sprites */
  103.         if (colortable[i+64*4] == 0x10) colortable[i+64*4] = 0;    /* preserve transparency */
  104.     }
  105.  
  106.     /* radar dots lookup table */
  107.     /* they use colors 0-3, I think */
  108.     for (i = 0;i < 4;i++)
  109.         COLOR(2,i) = i;
  110.  
  111.     /* now the stars */
  112.     for (i = 32;i < 32 + 64;i++)
  113.     {
  114.         int bits;
  115.         int map[4] = { 0x00, 0x88, 0xcc, 0xff };
  116.  
  117.         bits = ((i-32) >> 0) & 0x03;
  118.         palette[3*i] = map[bits];
  119.         bits = ((i-32) >> 2) & 0x03;
  120.         palette[3*i + 1] = map[bits];
  121.         bits = ((i-32) >> 4) & 0x03;
  122.         palette[3*i + 2] = map[bits];
  123.     }
  124. }
  125.  
  126. int bosco_vh_start(void)
  127. {
  128.     int generator;
  129.     int x,y;
  130.     int set = 0;
  131.  
  132.     if (generic_vh_start() != 0)
  133.         return 1;
  134.  
  135.     if ((dirtybuffer2 = malloc(videoram_size)) == 0)
  136.         return 1;
  137.     memset(dirtybuffer2,1,videoram_size);
  138.  
  139.     if ((tmpbitmap1 = osd_create_bitmap(32*8,32*8)) == 0)
  140.     {
  141.         free(dirtybuffer2);
  142.         generic_vh_stop();
  143.         return 1;
  144.     }
  145.  
  146.     /* precalculate the star background */
  147.     /* this comes from the Galaxian hardware, Bosconian is probably different */
  148.     total_stars = 0;
  149.     generator = 0;
  150.  
  151.     for (x = 255;x >= 0;x--)
  152.     {
  153.         for (y = 511;y >= 0;y--)
  154.         {
  155.             int bit1,bit2;
  156.  
  157.  
  158.             generator <<= 1;
  159.             bit1 = (~generator >> 17) & 1;
  160.             bit2 = (generator >> 5) & 1;
  161.  
  162.             if (bit1 ^ bit2) generator |= 1;
  163.  
  164.             if (x >= Machine->drv->visible_area.min_x &&
  165.                     x <= Machine->drv->visible_area.max_x &&
  166.                     ((~generator >> 16) & 1) &&
  167.                     (generator & 0xff) == 0xff)
  168.             {
  169.                 int color;
  170.  
  171.                 color = (~(generator >> 8)) & 0x3f;
  172.                 if (color && total_stars < MAX_STARS)
  173.                 {
  174.                     stars[total_stars].x = x;
  175.                     stars[total_stars].y = y;
  176.                     stars[total_stars].col = Machine->pens[color + STARS_COLOR_BASE];
  177.                     stars[total_stars].set = set;
  178.                     if (++set > 3)
  179.                         set = 0;
  180.  
  181.                     total_stars++;
  182.                 }
  183.             }
  184.         }
  185.     }
  186.     *bosco_staronoff = 1;
  187.  
  188.     displacement = 1;
  189.  
  190.     return 0;
  191. }
  192.  
  193.  
  194. /***************************************************************************
  195.  
  196.   Stop the video hardware emulation.
  197.  
  198. ***************************************************************************/
  199. void bosco_vh_stop(void)
  200. {
  201.     osd_free_bitmap(tmpbitmap1);
  202.     free(dirtybuffer2);
  203.     generic_vh_stop();
  204. }
  205.  
  206.  
  207.  
  208. WRITE_HANDLER( bosco_videoram2_w )
  209. {
  210.     if (bosco_videoram2[offset] != data)
  211.     {
  212.         dirtybuffer2[offset] = 1;
  213.  
  214.         bosco_videoram2[offset] = data;
  215.     }
  216. }
  217.  
  218.  
  219.  
  220. WRITE_HANDLER( bosco_colorram2_w )
  221. {
  222.     if (bosco_colorram2[offset] != data)
  223.     {
  224.         dirtybuffer2[offset] = 1;
  225.  
  226.         bosco_colorram2[offset] = data;
  227.     }
  228. }
  229.  
  230.  
  231. WRITE_HANDLER( bosco_flipscreen_w )
  232. {
  233.     if (flipscreen != (~data & 1))
  234.     {
  235.         flipscreen = ~data & 1;
  236.         memset(dirtybuffer,1,videoram_size);
  237.         memset(dirtybuffer2,1,videoram_size);
  238.     }
  239. }
  240.  
  241. WRITE_HANDLER( bosco_scrollx_w )
  242. {
  243.     bosco_scrollx = data;
  244. }
  245.  
  246. WRITE_HANDLER( bosco_scrolly_w )
  247. {
  248.     bosco_scrolly = data;
  249. }
  250.  
  251. WRITE_HANDLER( bosco_starcontrol_w )
  252. {
  253.     bosco_starcontrol = data;
  254. }
  255.  
  256.  
  257. /***************************************************************************
  258.  
  259.   Draw the game screen in the given osd_bitmap.
  260.   Do NOT call osd_update_display() from this function, it will be called by
  261.   the main emulation engine.
  262.  
  263. ***************************************************************************/
  264. void bosco_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  265. {
  266.     int offs,sx,sy;
  267.  
  268.  
  269.     /* for every character in the Video RAM, check if it has been modified */
  270.     /* since last time and update it accordingly. */
  271.     for (offs = videoram_size - 1;offs >= 0;offs--)
  272.     {
  273.         if (dirtybuffer2[offs])
  274.         {
  275.             int flipx,flipy;
  276.  
  277.  
  278.             dirtybuffer2[offs] = 0;
  279.  
  280.             sx = offs % 32;
  281.             sy = offs / 32;
  282.             flipx = ~bosco_colorram2[offs] & 0x40;
  283.             flipy = bosco_colorram2[offs] & 0x80;
  284.             if (flipscreen)
  285.             {
  286.                 sx = 31 - sx;
  287.                 sy = 31 - sy;
  288.                 flipx = !flipx;
  289.                 flipy = !flipy;
  290.             }
  291.  
  292.             drawgfx(tmpbitmap1,Machine->gfx[0],
  293.                     bosco_videoram2[offs],
  294.                     bosco_colorram2[offs] & 0x3f,
  295.                     flipx,flipy,
  296.                     8*sx,8*sy,
  297.                     0,TRANSPARENCY_NONE,0);
  298.         }
  299.     }
  300.  
  301.     /* update radar */
  302.     for (offs = videoram_size - 1;offs >= 0;offs--)
  303.     {
  304.         if (dirtybuffer[offs])
  305.         {
  306.             int flipx,flipy;
  307.  
  308.  
  309.             dirtybuffer[offs] = 0;
  310.  
  311.             sx = (offs % 32) ^ 4;
  312.             sy = offs / 32 - 2;
  313.             flipx = ~colorram[offs] & 0x40;
  314.             flipy = colorram[offs] & 0x80;
  315.             if (flipscreen)
  316.             {
  317.                 sx = 7 - sx;
  318.                 sy = 27 - sy;
  319.                 flipx = !flipx;
  320.                 flipy = !flipy;
  321.             }
  322.  
  323.             drawgfx(tmpbitmap,Machine->gfx[0],
  324.                     videoram[offs],
  325.                     colorram[offs] & 0x3f,
  326.                     flipx,flipy,
  327.                     8*sx,8*sy,
  328.                     &radarvisibleareaflip,TRANSPARENCY_NONE,0);
  329.         }
  330.     }
  331.  
  332.  
  333.     /* copy the temporary bitmap to the screen */
  334.     {
  335.         int scrollx,scrolly;
  336.  
  337.  
  338.         if (flipscreen)
  339.         {
  340.             scrollx = (bosco_scrollx +32);//- 3*displacement) + 32;
  341.             scrolly = (bosco_scrolly + 16) - 32;
  342.         }
  343.         else
  344.         {
  345.             scrollx = -(bosco_scrollx);
  346.             scrolly = -(bosco_scrolly + 16);
  347.         }
  348.  
  349.         copyscrollbitmap(bitmap,tmpbitmap1,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  350.     }
  351.  
  352.  
  353.     /* radar */
  354.     if (flipscreen)
  355.         copybitmap(bitmap,tmpbitmap,0,0,0,0,&radarvisibleareaflip,TRANSPARENCY_NONE,0);
  356.     else
  357.         copybitmap(bitmap,tmpbitmap,0,0,28*8,0,&radarvisiblearea,TRANSPARENCY_NONE,0);
  358.  
  359.  
  360.     /* draw the sprites */
  361.     for (offs = 0;offs < spriteram_size;offs += 2)
  362.     {
  363.         sx = spriteram[offs + 1] - displacement;
  364. if (flipscreen) sx += 32;
  365.         sy = 225 - spriteram_2[offs] - displacement;
  366.  
  367.         drawgfx(bitmap,Machine->gfx[1],
  368.                 (spriteram[offs] & 0xfc) >> 2,
  369.                 spriteram_2[offs + 1] & 0x3f,
  370.                 spriteram[offs] & 1,spriteram[offs] & 2,
  371.                 sx,sy,
  372.                 flipscreen ? &spritevisibleareaflip : &spritevisiblearea,TRANSPARENCY_THROUGH,Machine->pens[0]);
  373.     }
  374.  
  375.  
  376.     /* draw the dots on the radar and the bullets */
  377.     for (offs = 0; offs < bosco_radarram_size;offs++)
  378.     {
  379.         int x,y;
  380.  
  381.  
  382.         x = bosco_radarx[offs] + ((~bosco_radarattr[offs] & 0x01) << 8) - 2;
  383.         y = 235 - bosco_radary[offs];
  384.         if (flipscreen)
  385.         {
  386.             x -= 1;
  387.             y += 2;
  388.         }
  389.  
  390.         drawgfx(bitmap,Machine->gfx[2],
  391.                 ((bosco_radarattr[offs] & 0x0e) >> 1) ^ 0x07,
  392.                 0,
  393.                 flipscreen,flipscreen,
  394.                 x,y,
  395.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,3);
  396.     }
  397.  
  398.  
  399.     /* draw the stars */
  400.     if ((*bosco_staronoff & 1) == 0)
  401.     {
  402.         int bpen;
  403.  
  404.         bpen = Machine->pens[0];
  405.         for (offs = 0;offs < total_stars;offs++)
  406.         {
  407.             int x,y;
  408.             int set;
  409.             int starset[4][2] = {{0,3},{0,1},{2,3},{2,1}};
  410.  
  411.             x = (stars[offs].x + stars_scrollx) % 224;
  412.             y = (stars[offs].y + stars_scrolly) % 224;
  413.  
  414.             set = (bosco_starblink[0] & 1) + ((bosco_starblink[1] & 1) << 1);
  415.  
  416.             if (((stars[offs].set == starset[set][0]) ||
  417.                  (stars[offs].set == starset[set][1])))
  418.             {
  419.                 if (read_pixel(bitmap, x, y) == bpen)
  420.                 {
  421.                     plot_pixel(bitmap, x, y, stars[offs].col);
  422.                 }
  423.             }
  424.         }
  425.     }
  426. }
  427.  
  428. void bosco_vh_interrupt(void)
  429. {
  430.     int speedsx[8] = { -1, -2, -3, 0, 3, 2, 1, 0 };
  431.     int speedsy[8] = { 0, -1, -2, -3, 0, 3, 2, 1 };
  432.  
  433.     stars_scrollx += speedsx[bosco_starcontrol & 7];
  434.     stars_scrolly += speedsy[(bosco_starcontrol & 56) >> 3];
  435. }
  436.